#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Copyright (c) 2022 - 2025 Detlev Offenbach <detlev@die-offenbachs.de>
#
# This script installs all packages eric depends on.

"""
Installation script for the eric IDE dependencies.
"""

import contextlib
import subprocess  # secok
import sys


def exit(rcode=0):
    """
    Exit the install script.

    @param rcode result code to report back
    @type int
    """
    print()

    if sys.platform.startswith(("win", "cygwin")):
        with contextlib.suppress(EOFError):
            input("Press enter to continue...")  # secok

    sys.exit(rcode)


def pipInstall(packageName, proxy):
    """
    Install the given package via pip.

    @param packageName name of the package to be installed
    @type str
    @param proxy URL of a network proxy to be used
    @type str
    @return flag indicating a successful installation
    @rtype bool
    """
    ok = False
    args = [
        sys.executable,
        "-m",
        "pip",
        "install",
        "--prefer-binary",
        "--upgrade",
    ]
    if proxy:
        args.append(proxy)
    args.append(packageName)
    exitCode = subprocess.run(args).returncode  # secok
    ok = exitCode == 0

    return ok


def main():
    """
    Function to install the eric dependencies.
    """
    requiredPackages = (
        "PyQt6>=6.8.0",
        "PyQt6-Graphs>=6.8.0",
        "PyQt6-WebEngine>=6.8.0",
        "PyQt6-QScintilla>=2.13.0",
        "tomlkit",
        "asttokens",
        "EditorConfig",
        "Pygments",
        "parso",
        "jedi",
        "packaging",
        "cyclonedx-bom>=5.4.0",
        "trove-classifiers",
        "spdx-license-list>=3.26.0",
        "black>=22.6.0",
        "isort>=5.10.0",
        "coverage>=6.5.0",
        "semver",
        "pipdeptree",
        "watchdog>=5.0.0",
        "psutil",
        "requests",
    )
    optionalPackages = (
        "docutils",
        "Markdown",
        "pyyaml",
        "chardet",
        "pyenchant",
        "wheel",
        "esprima",
        "fido2",
        "pyusb>=1.2.0",
    )
    optionalWindowsPackages = (
        "pywin32>=1.0",
        "command-runner",
    )

    if "--proxy" in sys.argv:
        proxyIndex = sys.argv.index("--proxy")
        proxy = sys.argv[proxyIndex + 1]
        del sys.argv[proxyIndex : proxyIndex + 2]
    else:
        proxy = None

    packages = []
    if len(sys.argv) == 2:
        if sys.argv[1] == "--all":
            packages = requiredPackages + optionalPackages
            if sys.platform.startswith(("win", "cygwin")):
                packages += optionalWindowsPackages
        elif sys.argv[1] == "--required":
            packages = requiredPackages
        elif sys.argv[1] == "--optional":
            packages = optionalPackages
            if sys.platform.startswith(("win", "cygwin")):
                packages += optionalWindowsPackages

    if not packages:
        print("Usage:")
        print("    install-dependencies [--proxy url] --all | --optional | --required")
        print("where:")
        print("    --all         install all dependencies")
        print("    --optional    install all optional dependencies")
        print("    --required    install all required dependencies")

        exit(42)

    failedPackages = []
    for package in packages:
        ok = pipInstall(package, proxy)
        if not ok:
            failedPackages.append(package)

    print()
    print("Installation Summary")
    print("--------------------")
    if failedPackages:
        print("These packages could not be installed:")
        for package in failedPackages:
            print("    " + package)
    else:
        print("All packages installed successfully.")

    exit(0)


if __name__ == "__main__":
    main()

#
# eflag: noqa = M-801
